#include "E1.h"

const uint8_t TUBE_NUMS[11][2] = {
    //e d c b a x x x x x x x x bp g f
    {0xF8, 0x01},// 数字0 : 11111100
    {0x30, 0x00},// 数字1 : 01100000
    {0xD8, 0x02},// 数字2 : 11011010
    {0x78, 0x02},// 数字3 : 11110010
    {0x30, 0x03},// 数字4 : 01100110
    {0x68, 0x03},// 数字5 : 10110110
    {0xE8, 0x03},// 数字6 : 10111110
    {0x38, 0x00},// 数字7 : 11100000
    {0xF8, 0x03},// 数字8 : 11111110
    {0x38, 0x03},// 数字9 : 11100110
    {0x00, 0x00}
};


/*********************************************************************************************
函数名:    setPWM
入口参数:  periph:i2c外设  address:i2c地址  num:LED灯编号  on:电位上升沿的时间  off:电位下降沿的时间
出口参数： 无
返回值：   无
作者：     XQii
日期:      2023/4/24
调用描述:  设置E1子板中LED灯的占空比
**********************************************************************************************/
void setPWM(uint32_t periph,uint8_t address,uint8_t num, uint16_t on, uint16_t off)//Set signal PWM
{
    //Set signal PWM
    i2c_byte_write(periph, address, LED0_ON_L + 4 * num, on);
    i2c_byte_write(periph, address, LED0_ON_H + 4 * num, on >> 8);
    i2c_byte_write(periph, address, LED0_OFF_L + 4 * num, off);
    i2c_byte_write(periph, address, LED0_OFF_H + 4 * num, off >> 8);
}


/*********************************************************************************************
函数名:    setPWM_off
入口参数:  periph:i2c外设  address:i2c地址
出口参数： 无
返回值：   无
作者：     XQii
日期:      2023/4/24
调用描述:  关闭E1子板中LED中的RGB三色灯
**********************************************************************************************/
void setPWM_off(uint32_t periph, uint8_t address)
{
    //turn off LED
    i2c_byte_write(periph, address, ALLLED_ON_L, 0);
    i2c_byte_write(periph, address, ALLLED_ON_H, 0);
    i2c_byte_write(periph, address, ALLLED_OFF_L, 0);
    i2c_byte_write(periph, address, ALLLED_OFF_H, 0);
}


/*********************************************************************************************
函数名:    e1_init
入口参数:  address:该芯片的i2c起始地址
出口参数： 无
返回值：   初始化后的i2c地址结构体，如果初始化成功则结构体中的flag为1
作者：     XQii
日期:      2023/4/24
调用描述:  初始化E1子板中的某个芯片
**********************************************************************************************/
i2c_addr_def e1_init(uint8_t address)
{
    i2c_addr_def result;
    uint8_t i;
    /*get e1 address*/

    for (i = 0; i < 4; ++i)
    {
        result = get_board_address(address);

        /*write cmd to i2cx to enable s1*/
        if (result.flag == 1)
        {
            if (result.addr <= (PCA9685_ADDRESS_E1 + 8))
                pca9685_init(result.periph, result.addr);
            else if (result.addr >= HT16K33_ADDRESS_E1)
                ht16k33_init(result.periph, result.addr);
        }
    }
    /*return address_def struct*/
    return result;
}


/*********************************************************************************************
函数名:    e1_all_init
入口参数:  *e1_address:指向所有E1子板的指针  e1_rgb_addr:E1子板的PCA9685芯片基地址  e1_tube_addr:E1子板的HT16K33芯片基地址
出口参数： 无
返回值：   无
作者：     XQii
日期:      2023/4/24
调用描述:  初始化所有E1子板
**********************************************************************************************/
void e1_all_init(e1_addr_def *e1_address, uint8_t e1_rgb_addr, uint8_t e1_tube_addr)
{
    uint8_t i;
    for (i = 0; i < 4; ++i)
    {
        e1_address->rgb_addr[i] = e1_init(e1_rgb_addr + i * 2);
        e1_address->tube_addr[i] = e1_init(e1_tube_addr + i * 2);
    }
}


/*********************************************************************************************
函数名:    pca9685_init
入口参数:  periph:i2c外设  address:i2c地址
出口参数： 无
返回值：   无
作者：     XQii
日期:      2023/4/24
调用描述:  初始化E1子板中PCA9685芯片
**********************************************************************************************/
void pca9685_init(uint32_t periph, uint8_t address)
{
    i2c_byte_write(periph, address, PCA9685_MODE1, 0x0);
    setPWM_off(periph, address);
}


/*********************************************************************************************
函数名:    ht16k33_init
入口参数:  periph:i2c外设  address:i2c地址
出口参数： 无
返回值：   无
作者：     XQii
日期:      2023/4/24
调用描述:  初始化E1子板中HT16K33芯片
**********************************************************************************************/
void ht16k33_init(uint32_t periph, uint8_t address)
{
    i2c_cmd_write(periph, address, SYSTEM_ON_E1);
    i2c_cmd_write(periph, address, ROW_OUTPUT);
    ht16k33_RAM_init(periph, address);
    i2c_cmd_write(periph, address, TUBE_ON);

}


/*********************************************************************************************
函数名:    ht16k33_RAM_init
入口参数:  periph:i2c外设  address:i2c地址
出口参数： 无
返回值：   无
作者：     XQii
日期:      2023/4/24
调用描述:  初始化ht16k33芯片中显示存储器RAM
**********************************************************************************************/
void ht16k33_RAM_init(uint32_t periph, uint8_t address)
{
    uint8_t i;
    // clear RAM in kt16k33
    for (i = 0; i < 16; ++i)
    {
        i2c_byte_write(periph, address, i, 0x00);
    }
}


/*********************************************************************************************
函数名:    display_tube
入口参数:  val:要显示的数值  e1_tube_addr:数码管的i2c地址结构体
出口参数： 无
返回值：   无
作者：     XQii
日期:      2023/4/24
调用描述:  将RAM缓存中的内容显示到数码管上
**********************************************************************************************/
void display_tube(uint16_t val, i2c_addr_def e1_tube_addr)
{
    if (val > 9999)
        return;

    uint8_t buf[4];
    uint8_t i, bits;
    for (i = 0; i < 4 && val; i++)
    {
        buf[i] = val % 10;
        val /= 10;
    }
    bits = i == 0 ? 1 : i;

    ht16k33_RAM_init(e1_tube_addr.periph, e1_tube_addr.addr);

    // write data to i2c
    for (i = 4; i > 4 - bits; --i)
    {
        uint8_t addr = i * 2;
        i2c_write(e1_tube_addr.periph, e1_tube_addr.addr, addr, TUBE_NUMS[buf[4 - i]], 2);
    }
}
